from fastapi import APIRouter,Depends,Request,HTTPException, status,Query
from pydantic import BaseModel
from jose import JWTError, jwt
from datetime import timedelta
from typing import Optional, List
from novelapp.config.database import connect
from novelapp.api.auth import create_access_token, get_user,ACCESS_TOKEN_EXPIRE_MINUTES
from novelapp.models.models import User,Collect,Books,UserLikeStats,Nlist,Suggestion
from novelapp.common.common import returnData,setLog
from mongoengine.queryset.visitor import Q
from pymongo import errors as mongo_errors
import json
import bcrypt
from mongoengine.errors import DoesNotExist, ValidationError
from datetime import datetime
from wechatpy import WeChatClient
client = WeChatClient('wxe6ab1928d875148f', '6d4bc3a5b445a918eb1e6993fac0e037')

router = APIRouter()

logger = setLog('noveapp.log')

@router.get('/login/')
async def login(code: Optional[str] = Query(None, description="Author code")):
    
    if not code:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="信息有误")  
        
    session_info = client.wxa.code_to_session(code)
    # 根据 session_info 中的信息进行后续处理，比如获取用户信息等
    openid = session_info['openid']

    nickname = f"用户_{openid[-6:]}"
    user = User.objects(openid=openid).first()
    if not user:
        # 如果用户不存在，则创建用户
        user = User(openid=openid, nickname=nickname, level=1).save()
        user = User.objects(openid=openid).first()
    access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
    access_token = create_access_token(data={"sub": user.openid})
    
    return returnData(200, '登录成功', {"access_token": access_token, "token_type": "bearer","user":user.get_user_info()})


    

# 你可以在其他路由中使用`get_user`函数来验证JWT
# 例如：
@router.get("/get_user/", dependencies=[Depends(get_user)])
async def read_items(user: User = Depends(get_user)):
    if user:
        return returnData(200, '查询成功', user.get_user_info())
    else:
        return returnData(401, 'Unauthorized', None)


class Item(BaseModel):
    book_id: str
@router.post("/add_book_to_collect/")
async def add_book_to_collect(item: Item, user: User = Depends(get_user)):

    book_id = item.book_id
    if not book_id:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="信息有误")     
        
    # BooksDetail = Books.objects(id=book_id).first().get_book_info()        
    book = Books.objects.get(id=book_id)
            # Books.objects.get(id=ObjectId(book_id))
    # logger.error(f"ls: {book_id}")
    
    try:
        # 尝试查找是否已存在该用户对该书籍的收藏记录
        existing_collect = Collect.objects(user=user.id, book=book.id).first()
        if existing_collect:
            existing_collect.delete()
            return returnData(200, '已删除重复收藏记录', None)
        else:
            collect = Collect(book=book, user=user.id).save()
            return returnData(200, '书籍添加到收藏成功', collect.get_shujia_info())
    except DoesNotExist:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="书籍不存在")
    except ValidationError as e:
        
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="请求数据无效")
 
 
 
@router.get("/get_user_collected_books/")
async def get_user_collected_books(user: User = Depends(get_user)):
    try:
        collected_books_info = Collect.get_all_books_for_user(user)
        return returnData(200, '查询成功', collected_books_info)
    except Exception as e:
        logger.error(f"获取用户收藏书籍信息出错: {e}")
        raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="服务器内部错误")


@router.get("/my_shudan/")
async def my_shudan(sd_type: Optional[str] = Query('my', description="type (my or like)"), user: User = Depends(get_user),
                    page: int = Query(1, gt=0, description="Page number"),
                    page_size: int = Query(10, gt=0, le=100, description="Number of items per page")):
    try:
        
        if sd_type =='my':
            query = Q(created_by=user)
            query &= Q(display=1)
            
            nlists = Nlist.objects(query)
        elif sd_type == 'like':
            # 获取用户点赞数相关文档对象
            user_like_stats = UserLikeStats.objects(user_id=user.id).first()
            if not user_like_stats:
                return returnData(400, '未找到用户点赞记录', {})

            liked_nlist_ids = list(user_like_stats.liked_nlists.keys())  # 获取字典的所有键，即点赞的 nlist_id
            if not liked_nlist_ids:
                return returnData(200, '没有点赞任何书单', {})

            query = Q(id__in=liked_nlist_ids)  # 使用 nlist_id 进行查询
            
            query &= Q(display=1)
            nlists = Nlist.objects(query)

       
        
        nlists = nlists.order_by('-created_at')
        # 计算分页参数
        skip = (page - 1) * page_size
        limit = page_size

        # 添加分页
        nlists = nlists.skip(skip).limit(limit)

        result = []
        for nlist in nlists:
            if nlist:  # 添加空值检查
                nlist_info = nlist.get_nlist_info()
                nlist_info["book_count"] = len(nlist.books)

                result.append(nlist_info)

        total_count = Nlist.objects(query).count()

        return returnData(200, '获取书单列表成功', {
            "page": page,
            "page_size": page_size,
            "total_count": total_count,
            "bookLists": result
        })
    except Exception as e:
        logger.error(f"--------my_shudan-----{e}")
        raise HTTPException(status_code=500, detail="内部服务器错误")

class upUser(BaseModel):
    nickname: str
@router.post("/up_user/")
async def up_user(reqs: upUser, user: User = Depends(get_user)):
    nickname = reqs.nickname
    
    # user = User.objects.get(openid='18800000000')
    
    # return returnData(200, '昵称修改成功', {user.get_user_info()})
    
    # logger.error(f"Error in upUser: {nickname}")
    # logger.error(f"Error in upUser: {user}")
    
    
    try:
        # 检查book_id是否有效
                # 更新当前用户的昵称
        user.nickname = nickname
        user.save()
        return returnData(200, '昵称修改成功', {})
    except ValidationError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        logger.error(f"Error in upUser: {e}")
        raise HTTPException(status_code=500, detail="内部服务器错误")
 
class AddSuggestion(BaseModel):
    content: str

@router.post("/add_suggestion/")
async def add_suggestion(reqs: AddSuggestion, user: User = Depends(get_user)):
    content = reqs.content

    try:
        # 创建建议对象
        new_suggestion = Suggestion(
            user_id=user.id,
            content=content,
            added_at=datetime.now()
        )
        new_suggestion.save()

        return returnData(200, '建议添加成功', {})

    except mongo_errors.ValidationError as e:
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        logger.error(f"Error in add_suggestion: {e}")
        raise HTTPException(status_code=500, detail="内部服务器错误")    
        
        
        
# 鸿蒙os  接口
# 定义注册请求的数据模型
class RegisterRequest(BaseModel):
    mobile: str
    nickname: str
    password: str        
        
@router.post("/hmos_reg/")
async def hmos_reg(reqs: RegisterRequest):
    mobile = reqs.mobile
    nickname = reqs.nickname
    password = reqs.password

    # 检查手机号是否已被注册
    existing_user = User.objects(mobile=mobile).first()
    if existing_user:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="手机号已被注册，请更换手机号")

    # 对密码进行哈希处理（使用bcrypt示例，你也可以选择其他合适的加密方式）
    hashed_password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt())

    try:
        # 创建新用户并保存到数据库
        new_user = User(
            mobile=mobile,
            openid=mobile,
            nickname=nickname,
            password=hashed_password.decode('utf-8'),  # 存储哈希后的密码字符串
            level=1,  # 可以根据实际情况设置初始等级等其他默认属性
            reg_type=1  # 可以根据实际情况设置初始等级等其他默认属性
        ).save()
        
        # logger.error(f"Error in  reg1 : {new_user.openid}")
        # new_user.openid = str(new_user.id)
        # new_user.save()  # 再次保存用户文档，将openid更新到数据库中
        # logger.error(f"Error in  reg2 : {new_user.openid}")
        # 注册成功后，直接进行登录操作，生成并返回token
        access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
        access_token = create_access_token(data={"sub": mobile})
        
        user = User.objects(openid=mobile).first()

        
        return returnData(200, '登录成功', {"access_token": access_token, "token_type": "bearer","mobile": user.mobile,"nickname": user.nickname})    
    except ValidationError as e:
        logger.error(f"Error in  reg5 : {e}")
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        logger.error(f"Error in  reg6 : {e}")
        raise HTTPException(status_code=500, detail="内部服务器错误")        
        
        
# 定义登录请求的数据模型（基于手机号和密码）
class LoginRequest(BaseModel):
    mobile: str
    password: str

@router.post("/hmos_login/")
async def hmos_login(reqs: LoginRequest):
    mobile = reqs.mobile
    password = reqs.password

    user = User.objects(mobile=mobile).first()
    if not user:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="用户不存在，请先注册")

    # 验证密码是否正确（使用bcrypt验证，与注册时的加密方式对应）
    if not bcrypt.checkpw(password.encode('utf-8'), user.password.encode('utf-8')):
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="密码错误")

    access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
    access_token = create_access_token(data={"sub": user.openid})

    return returnData(200, '登录成功', {"access_token": access_token, "token_type": "bearer","mobile": user.mobile,"nickname": user.nickname})        
   


from fastapi.responses import HTMLResponse
@router.get("/privacy-policy")
async def privacy_policy():
    html_content = """
    <html>
        <head>
            <title>隐私声明</title>
            <style>
                body { font-family: Arial, sans-serif; }
                .container { width: 80%; margin: auto; }
                h1 { color: #333; }
                p { color: #666; }
            </style>
        </head>
        <body>
            <div class="container">
                <h1>隐私声明</h1>
                <p><strong>引言</strong></p>
                <p>我们重视您的隐私和个人信息安全。本隐私声明旨在向您说明我们如何收集、使用、披露和保护您的个人信息。请仔细阅读以下内容，以了解我们对用户数据的处理方式。</p>
                
                <p><strong>1. 收集信息的类型</strong></p>
                <p>我们可能会收集以下类型的个人信息：电子邮件、电话号码等。</p>
                
                <p><strong>2. 信息的使用目的</strong></p>
                <p>我们收集的信息将用于以下目的：提供和改进我们的服务、个性化您的用户体验、进行市场研究和分析。</p>
                
                <p><strong>3. 信息共享</strong></p>
                <p>我们不会将您的个人信息出售或与第三方共享，除非获得您的明确同意或遵守法律、法规或合法程序的要求。</p>
                
                <p><strong>4. 数据安全</strong></p>
                <p>我们采取行业标准的安全措施来保护您的个人信息不被未经授权的访问和泄露。</p>
                
                <p><strong>5. 用户权利</strong></p>
                <p>您有权访问、更正、删除或要求我们不使用您的个人信息。如需行使这些权利，请联系我们的隐私官。</p>
                
                <p><strong>6. 未成年人隐私</strong></p>
                <p>我们的服务不针对未成年人。如果我们意识到收集了未成年人的个人信息，将采取措施删除这些信息。</p>
                
                <p><strong>7. 隐私政策更新</strong></p>
                <p>我们可能会不时更新本隐私声明。任何重大变更将通过我们的网站通知您，并在变更生效前提供足够的时间供您审阅。</p>
                
                <p><strong>8. 联系信息</strong></p>
                <p>如果您对本隐私声明有任何疑问或需要进一步的信息，请通过以下方式联系我们：[602322195@qq.com]</p>
                
                <p><strong>9. 第三方链接</strong></p>
                <p>我们的网站可能包含指向第三方网站的链接。这些第三方网站的隐私实践不受本隐私声明约束。我们建议您查看这些网站的隐私政策。</p>
                
                <p><strong>10. 同意</strong></p>
                <p>使用我们的服务即表示您同意本隐私声明中的条款。</p>
            </div>
        </body>
    </html>
    """
    return HTMLResponse(content=html_content)
   
        
# @router.get("/get_user_cat/", dependencies=[Depends(get_user)])
# async def get_user_cat(user: User = Depends(get_user)):\
#     print(user.openid)
    
    
    
# # 更新用户信息
# @router.put("/users/{user_id}")
# async def update_user(user_id: str, user_data: UserInDB, user: User = Depends(get_user)):
#     user_to_update = User.objects(id=ObjectId(user_id)).first()
#     if not user_to_update:
#         raise HTTPException(status_code=404, detail="User not found")
#     user_to_update.nickname = user_data.nickname
#     user_to_update.level = user_data.level
#     user_to_update.save()
#     return {"id": str(user_to_update.id), "nickname": user_to_update.nickname, "level": user_to_update.level}    
    
# # 删除用户
# @router.delete("/users/{user_id}")
# async def delete_user(user_id: str, user: User = Depends(get_user)):
#     user_to_delete = User.objects(id=ObjectId(user_id)).first()
#     if not user_to_delete:
#         raise HTTPException(status_code=404, detail="User not found")
#     user_to_delete.delete()
#     return {"message": "User deleted"}